(function() {
	var EventEmitter = require('events').EventEmitter;
	var hprose = require("hprose");
	var dbname = "Gaubee_test_2";
	var Fiber = require("fibers");
	var fs = require("fs");
	var ip = "192.168.31.225";
	var ip = "121.40.72.93";
	var __rev_dirname = __dirname;
	var mongodb_proxy = hprose.Client.create('tcp://' + ip + ':7074/', ["createDB", "createCollection", "createDBAndCollection",
		"insert",
		"findAll", "findOne", "findById", "findList",
		"update",
		"remove",
		"reflectMethod"
	], {
		throwerror: true
	});
	// mongodb_proxy.onerror = function(e) {
	// 	console.log("onError", e)
	// 	throw e;
	// };

	var _CREATED_COLLECTION_MAP = Object.create(null);
	var db = {
		refreshIndex: function(new_dbname) {
			var fileName = "data.cache.json";
			var new_dbnames = fs.existsSync(__rev_dirname + "/.db/mongodb_names.json") ? require(__rev_dirname + "/.db/mongodb_names.json") : [];
			if (!new_dbname) {
				new_dbname = new_dbnames[0];
			}
			//如果存在文件版本的数据库，则使用这个数据库，并导入到新的数据集
			if (fs.existsSync(__rev_dirname + "/.db/" + fileName) && !fs.existsSync(__rev_dirname + "/.db/.file.db.lock")) {
				console.log("发现文件版数据库");
				var _db = require(__rev_dirname + "/.db/data.cache.json");
				new_dbname = "O2O_" + (+new Date).toString(36);
				console.log("使用新的数据集：", new_dbname);
				db._init_mongo_proxy(new_dbname);
				new_dbnames.unshift(new_dbname);
				fs.writeFileSync(__rev_dirname + "/.db/mongodb_names.json", JSON.stringify(new_dbnames));
				console.log("开始录入文件数据");
				for (var db_name in _db) {
					if (_db.hasOwnProperty(db_name)) {
						//并不会触发对应的emit事件，因为db还没有exports出去，不会有注册的事件
						var arr_data = _db[db_name]
						console.log("表", db_name, "录入，共", arr_data.length, "条数据");

						var per_num = 1000;

						for (var index = 0; index < arr_data.length; index += per_num) {
							var post_data = arr_data.slice(index, index + per_num);
							post_data = post_data.map(function(item_data) {
								return [db_name, item_data];
							});
							console.time("发送数据");
							db.mulCall("insert", post_data);
							console.timeEnd("发送数据");
						}
					}
				}
				// fs.renameSync(__rev_dirname + "/.db/data.cache.json", __rev_dirname + "/.db/data.cache.to_" + new_dbname + ".json")
				fs.writeFileSync(__rev_dirname + "/.db/.file.db.lock", "");
			} else {
				console.log("使用现有数据集：", new_dbname);
				db._init_mongo_proxy(new_dbname);
			}
			dbname = new_dbname;
		},
		_init_mongo_proxy: function(new_dbname) {

			new_dbname && (dbname = new_dbname);
			console.time("初始化Mongodb代理数据库连接");
			var fiber = Fiber.current;
			mongodb_proxy.createDB(dbname, function(res) {
				fiber.run(res);
			});
			Fiber.yield();
			console.timeEnd("初始化Mongodb代理数据库连接");
		},
		_init_args: function(args) {
			var col_name = args[0];
			col_name = col_name.toLowerCase();
			args[0] = col_name; //col_name
			db._init_collection(col_name);
			args.unshift(dbname);
			return col_name;
		},
		_init_collection: function(col_name) {
			if (!_CREATED_COLLECTION_MAP[col_name]) {
				_CREATED_COLLECTION_MAP[col_name] = true;
				var fiber = Fiber.current;
				mongodb_proxy.createCollection(dbname, col_name, function(res) {
					// res = JSON.parse(res);
					fiber.run(res);
				});
				Fiber.yield();
			}
		},
		_call_proxy: function(method, args) {
			var col_name = db._init_args(args);
			// console.log(method,args)
			var fiber = Fiber.current;
			args.push(function(res) {
				res = JSON.parse(res);
				if (res.result === 'fail') {
					throwCusError(res.msg);
					return;
				}
				fiber.run(res.content);
			});
			mongodb_proxy[method].apply(mongodb_proxy, args);
			var res = Fiber.yield();
			return res;
		},
		mulCall: function(method, args) {
			args.forEach(function(params) {
				db._init_args(params);
			});
			var fiber = Fiber.current;
			mongodb_proxy.reflectMethod(method, JSON.stringify(args), function(res) {
				res = JSON.parse(res);
				if (res.result === 'fail') {
					throwCusError(res.msg);
					return;
				}
				res.content = res.content.map(function(res_item) {
					return JSON.parse(res_item).content;
				});
				fiber.run(res.content);
			});
			return Fiber.yield();
		},
		insert: function(col_name, obj, index) {
			obj._id || (obj._id = index);
			db.emit("insert", col_name, obj);
			db._call_proxy("insert", [col_name, JSON.stringify(obj)]);
		},
		find_by_id: function(col_name, id) {
			// logDomain("find_by_id");
			return id && db._call_proxy("findById", [col_name, id]);
		},
		find_one: function(col_name, obj) {
			console.log("find")
			return db._call_proxy("findOne", [col_name, obj ? JSON.stringify(db._parse_find_obj(obj)) : ""]);
		},
		find_last_one: function(col_name, obj, sortBy, no_asc) {
			if (sortBy) {
				var _sortBy = {};
				_sortBy[sortBy] = no_asc ? 1 : -1;
				_sortBy = JSON.stringify(_sortBy);
			} else {
				_sortBy = "";
			}
			return db._call_proxy("findList", [col_name, 1, 1, obj ? JSON.stringify(db._parse_find_obj(obj)) : "", _sortBy]);
		},
		find_list: function(col_name, obj, num, page) {
			return db._call_proxy("findList", [col_name, (parseInt(page) || 0) + 1, parseInt(num) || 0, obj ? JSON.stringify(db._parse_find_obj(obj)) : "", ""]);
		},
		find_all: function(col_name) {
			return db._call_proxy("findAll", [col_name]);
		},
		update: function(col_name, obj_index, obj) {
			return db._call_proxy("update", [col_name, obj_index, JSON.stringify(obj)]);
		},
		remove: function(col_name, obj_index) {
			return db._call_proxy("remove", [col_name, obj_index]);
		},
		remove_list: function(col_name, obj) {
			return db.find_list(col_name, obj).forEach(function(obj) {
				db.remove(col_name, obj._id)
			});
		},
		_sortBy: require("./skill").sortBy,
		_parse_find_obj: function(obj) {
			var res = Object.create({});
			Object.keys(obj).forEach(function(key) {
				var v = obj[key];
				if (v instanceof Object) {
					v = db._parse_find_obj(v);
					Object.keys(v).forEach(function(c_key) {
						res[key + "." + c_key] = v[c_key];
					});
				} else {
					res[key] = v;
				}
			});
			return res;
		}
	};
	db.__proto__ = EventEmitter.prototype;
	EventEmitter.call(db);
	module.exports = db;


}());